/**
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2007，所有权利保留。
 * 
 * 项目名：	rumba
 * 文件名：	OnceConstraint.java
 * 模块说明：	
 * 修改历史：
 * Nov 10, 2007 - lxm - 创建。
 */
package com.hd123.rumba.sysclock;

import java.text.ParseException;
import java.util.Date;
import java.util.Map;

import net.sf.hibernate.HibernateException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.exception.NoneException;
import com.hd123.rumba.mscb.constraint.IConstraint;
import com.hd123.rumba.runtime.FormatSettings;
import com.hd123.rumba.util.XMLUtil;

/**
 * 系统时钟一次性消息订阅约束条件。
 * <p>
 * 
 * 通过{@link #getContext()}序列化格式如下：
 * <p style="border: 1px dashed blue;background-color: gainsboro;">
 * <code>
 &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
 &lt;onceConstrant<br>
 &nbsp;&nbsp;datetime="2007-11-22 11:22:08"/&gt;
 </code>
 * </p>
 * 
 * @author lxm
 * 
 */
public class OnceConstraint implements IConstraint, IForTaskSchedule {

  private Date datetime = null;
  private Map<String, Object> dict = null;

  public String getContext() throws BusinessException {
    Document doc = XMLUtil.newDocument();
    Element eRoot = doc.createElement("onceConstraint");
    XMLUtil.writeDate(eRoot, "datetime", datetime);
    doc.appendChild(eRoot);
    return XMLUtil.transform(doc);
  }

  public void setContext(String context) throws BusinessException {
    Document doc = XMLUtil.parse(context);
    NodeList nlRoot = doc.getElementsByTagName("onceConstrant");
    try {
      if (nlRoot.getLength() == 0 || !(nlRoot.item(0) instanceof Element))
        throw new NoneException();
      Element eRoot = (Element) nlRoot.item(0);
      this.datetime = XMLUtil.readDate(eRoot, "datatime");
    } catch (NoneException e) {
      throw new BusinessException("无法识别的约束条件上下文(ConstraintContext)。");
    } catch (ParseException e) {
      throw new BusinessException("无法识别的约束条件上下文(ConstraintContext)。", e);
    }
  }

  public Map<String, Object> getDict() throws BusinessException {
    return dict;
  }

  public void setDict(Map<String, Object> dict) throws BusinessException {
    this.dict = dict;
  }

  public boolean isValid() throws BusinessException, HibernateException {
    assert this.datetime != null;
    assert this.dict != null;
    Date notifyTime = (Date) this.dict.get(CSysclock.DICT_NOTIFYTIME);
    assert notifyTime != null;
    return notifyTime.compareTo(this.datetime) == 0;
  }

  public String getDescription() throws BusinessException {
    return "于 " + FormatSettings.formatDatetime(FormatSettings.SDFyMdHm, this.datetime) + " 被触发。";
  }

  public void clear() throws BusinessException {
    this.dict = null;
    this.datetime = null;
  }

  public Date getNextTime(Date baseTime) throws BusinessException {
    assert this.datetime != null;
    if (baseTime == null)
      baseTime = new Date();
    if (this.datetime.after(baseTime))
      return this.datetime;
    else
      return null;
  }

  /** 触发日期与时间 */
  public Date getDatetime() {
    return datetime;
  }

  /** 触发日期与时间 */
  public void setDatetime(Date datetime) {
    this.datetime = datetime;
  }

}
